home *** CD-ROM | disk | FTP | other *** search
- Unit Engine3d;
- {
- 3D Engine, v3.01
- by Maple Leaf, 1996
- No fuckin rights reserved.
- last update: 4th May 1996
- }
-
- Interface
-
- Const
- Perspective : Boolean = True; { Default with perspective }
- ZoomFactor : LongInt = 220; { Zooming 220% as default }
- PiOver180 : Real = Pi/180;
- CenterX : LongInt = 160; { Center's coordinates }
- CenterY : LongInt = 100;
- ObserverX : LongInt = 0; { Defaults. See procedure SetObserver.. }
- ObserverY : LongInt = 0;
- ObserverDist : LongInt = 300; { Initial focus }
- CameraX : Longint = 0; { Initial camera coords in 3D space }
- CameraY : Longint = 0;
- CameraZ : Longint = 0;
-
- Var
- _3DX : LongInt; {-----------}
- _3DY : LongInt; { 3D coords }
- _3DZ : LongInt; {-----------}
- _2DX : LongInt; { 2D X }
- _2DY : LongInt; { 2D Y }
- { ---- Angles ---- }
- RotAngle, TiltAngle : Integer;
- CosA, CosB, SinA, SinB : Real;
- CosTab, SinTab : Array [0..359] of LongInt; { Integer(cosinus|sinus*256) }
- Xt, Yt, Zt, TmpEqu : LongInt;
-
- Procedure SetCenter (x,y:Integer);
- { Sets the center of the screen }
- Procedure SetAngles (Rotation,Tilt:Integer);
- { Sets the angles (horizontal rotation and tilt) }
- Procedure SetObserverPosition (x,y:LongInt; Focus:LongInt);
- { Sets the focus of the camera (e.g. the distance between the
- observer and the projection plane), and the 2D position (X,Y)
- of the observer in a plane parallel w/ the projection plane. }
- Procedure SetCamera (x,y,z:Longint);
- { Sets the (X,Y,Z) position of the camera in the virtual 3D space }
- { Or else: (X,Y,Z) will be the only point which has a FIXED position
- onto the 2D desktop (e.g. screen), for any rotations }
- Procedure MapCoordinates;
- { Default Floating-Point mapping routine. Translates a 3D point into a 2D one. }
- Procedure IntMapCoordinates;
- { Default integer-mapping routine. Translates a 3D point into a 2D one. }
- Procedure IntMapCoordinates2;
- { Second integer-mapping routine. Uses ZoomFactor=256=constant, for speed. }
- Procedure IncrAngle (var Angle:Integer; value:integer);
- { Increment or decrement the specified angle w/ a specified
- value, taking care of translating the result in the interval [0-359] }
-
- Implementation
- {$L engine3d}
-
- Procedure IntMapCoordinates;external;
- Procedure IntMapCoordinates2;external;
-
- Procedure SetCenter(x,y:Integer);assembler;
- asm
- mov ax,x
- db 66h; cbw
- db 66h; mov word ptr CenterX,ax { Screen center (X coordinate) }
- mov ax,y
- db 66h; cbw
- db 66h; mov word ptr CenterY,ax { Screen center (Y coordinate) }
- end;
-
- Procedure SetAngles(Rotation,Tilt:Integer);
- begin
- RotAngle:=Rotation;
- TiltAngle:=Tilt;
- IncrAngle(RotAngle,0);
- IncrAngle(TiltAngle,0);
- end;
-
- Procedure SetObserverPosition(x,y:LongInt; Focus:LongInt);assembler;
- asm
- db 66h; mov ax,word ptr x
- db 66h; neg ax
- db 66h; mov word ptr ObserverX,ax { Observer's X position }
- db 66h; mov ax,word ptr y
- db 66h; neg ax
- db 66h; mov word ptr ObserverY,ax { Observer's Y position }
- db 66h; mov ax,word ptr Focus
- db 66h; mov word ptr ObserverDist,ax { Distance from the observer to the projection plane (z=0) }
- end;
-
- Procedure MapCoordinates;
- var Xt,Yt,Zt : Real;
- OneOverZt : Real;
- begin
- { Init some vars, for speed }
- CosA:=Cos( RotAngle * PiOver180 );
- SinA:=Sin( RotAngle * PiOver180 );
- CosB:=Cos( TiltAngle* PiOver180 );
- SinB:=Sin( TiltAngle* PiOver180 );
- { Init camera (bring it to the virtual screen's center) }
- _3dx:=_3dx-CameraX;
- _3dy:=_3dy-CameraY;
- _3dz:=_3dz-CameraZ;
- { Calculations }
- Xt:= ObserverX + _3DX*CosA - _3DY*SinA;
- Yt:= ObserverY + (_3DX*SinA+_3DY*CosA)*SinB + _3DZ*CosB;
- if Perspective then begin
- Zt:= ObserverDist + (_3DX*SinA+_3DY*CosA)*CosB - _3DZ*SinB;
- _2DX:=CenterX+Trunc(Xt*ZoomFactor/Zt);
- _2DY:=CenterY-Trunc(Yt*ZoomFactor/Zt*13/16);
- end else begin
- _2DX:=CenterX+Trunc(Xt); { Faster, but less precise in aspect - no running points }
- _2DY:=CenterY-Trunc(Yt*13/16); { Faster, but less precise in aspect }
- end;
- end;
-
- Procedure IncrAngle(var Angle:Integer; value:integer);assembler;
- asm
- les di,Angle
- mov ax,value
- mov cx,es:[di]
- add cx,ax
- or cx,cx
- jl @Under
- cmp cx,359
- jg @Above
- mov es:[di],cx
- jmp @Ok
- @Above:
- sub cx,360
- mov es:[di],cx
- jmp @Ok
- @Under:
- mov ax,360
- add ax,cx
- mov es:[di],ax
- @Ok:
- end;
-
- Procedure SetCamera(x,y,z:longint);assembler;
- asm
- db 66h; mov ax,word ptr x
- db 66h; mov word ptr CameraX,ax
- db 66h; mov ax,word ptr y
- db 66h; mov word ptr CameraY,ax
- db 66h; mov ax,word ptr z
- db 66h; mov word ptr CameraZ,ax
- end;
-
- var k:word;
-
- Begin
- { Constructing default COS and SIN tables ... }
- for k:=0 to 359 do begin
- CosTab[k]:=LongInt(Trunc(cos(k*pi/180)*256));
- SinTab[k]:=LongInt(Trunc(sin(k*pi/180)*256));
- end;
- End.
-